home *** CD-ROM | disk | FTP | other *** search
- (Message mh:8)
- Resent: Mon, 25 Mar 91 10:19:23 PST
- Resent: qq11@uxb.liv.ac.uk (Alan Thew)
- Resent: Mon, 18 Mar 91 12:22:39 PST
- Resent: jcohn@nsf.gov (Johnathan Charles Cohn)
- Resent: rjg@sq.com (Bob Gibson)
- Resent: dak@sq.com (David Keldson)
- Resent: sow@cad.luth.se (Sven-Ove Westberg)
- Resent: cenkl@linus.mitre.org (Mike Cenkl)
- Resent: david@scocan.sco.com (David J Fiander)
- Return-Path: jamesp@metolius.WR
- To: luj@ecn.purdue.edu (Jun Lu), jkm@ctt.bellcore.COM (James Mcglashan),
- jmvogtle@gamera.cns.syr.edu (John M Vogtle),
- cks@hawkwind.utcs.toronto.edu (Chris Siebenmann),
- ccw@deakin.OZ.AU (Craig Warren), rr@mips.COM (Robert "Bob" Rodriguez),
- munck@Stars.Reston.Unisys.COM (Bob Munck)
- Cc: jamesp@metolius.WR.TEK.COM (James Perkins)
- Subject: Vmail - version 10/87DAS - part 3/3
- Reply-To: jamesp@metolius.WR.TEK.COM (James T. Perkins)
- X-Mailer: Rand MH 6.6 - Vmail 10/87DAS - Vmailtool V1.14 91/02/27
- Date: Mon, 11 Mar 91 11:46:40 PST
- From: James T Perkins <jamesp@metolius.WR>
- --------
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 3)."
- # Contents: load.c
- # Wrapped by jamesp@metolius on Mon Mar 11 11:20:05 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f load.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"load.c\"
- else
- echo shar: Extracting \"load.c\" \(11899 characters\)
- sed "s/^X//" >load.c <<'END_OF_load.c'
- X#ifndef lint
- Xstatic char *RCS_load_c = "$Id: load.c,v 1.5 90/07/31 11:29:15 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- load.c
- X
- X Routines to find folders, find all mail items in folders. Empty
- X folders are ignored.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X#include <ctype.h>
- X
- X
- X/* --------------------
- X Find all folders in mail directory, set up linked list.
- X-------------------- */
- Xvoid
- Xfind_folders()
- X{
- X struct direct *dp;
- X struct stat statbuf;
- X DIR *dirp;
- X int i, max = 0, n = 0, scmp();
- X char str[LEN], **fds, **ftmp;
- X folder tmp, last = (folder) NULL;
- X
- X (void)stat(mail_dir, &statbuf);
- X /* guess number of folders - 10 is an error bound */
- X max = statbuf.st_nlink+10;
- X#ifdef sparc
- X ftmp = fds = (char **) memalign((unsigned)8, (unsigned)(sizeof(char *) * max));
- X#else
- X ftmp = fds = (char **) malloc((unsigned)(sizeof(char *) * max));
- X#endif
- X dirp = opendir(mail_dir);
- X for(dp=readdir(dirp) ; dp != (struct direct *)NULL ; dp=readdir(dirp)) {
- X if(strcmp(dp->d_name, ".") == 0)
- X continue;
- X if(strcmp(dp->d_name, "..") == 0)
- X continue;
- X (void)sprintf(str, "%s/%s", mail_dir, dp->d_name);
- X (void)stat(str, &statbuf);
- X if(! (statbuf.st_mode & S_IFDIR))
- X continue;
- X if(! (statbuf.st_mode & S_IREAD) || ! (statbuf.st_mode & S_IWRITE)
- X || ! (statbuf.st_mode & S_IEXEC)) {
- X (void)printf("Folder %s unreadable.\n", dp->d_name);
- X continue;
- X }
- X if(n == max){
- X int offset = ftmp - fds; /* how far into fds */
- X
- X /*
- X * We just overflowed the guessed number of entries
- X * Let's try 10 more.
- X */
- X max += 10;
- X fds = (char **)realloc((char *)fds, (unsigned)(sizeof(char *) * max));
- X ftmp = fds + offset;
- X }
- X
- X *ftmp = NEWSTR(strlen(dp->d_name)+1);
- X (void)strcpy(*ftmp, dp->d_name);
- X n++, ftmp++;
- X }
- X (void)closedir(dirp);
- X if(n == 0) {
- X (void)printf("No folders.\n");
- X exit(1);
- X }
- X qsort((char *)fds, n, sizeof(char *), scmp);
- X for(i=0, ftmp=fds ; i < n ; ftmp++, i++) {
- X tmp = NEW(mail_folder);
- X tmp->name = *ftmp;
- X tmp->last = tmp->mail = (item) NULL;
- X tmp->pages = tmp->pagenum = 1;
- X tmp->valid = false;
- X tmp->prev = last;
- X tmp->next = (folder) NULL;
- X if(last != (folder) NULL)
- X last->next = tmp;
- X else
- X folders = tmp;
- X last = tmp;
- X }
- X}
- X
- X
- Xint
- Xscmp(p, q)
- X char **p, **q;
- X{
- X return(strcmp(*p, *q));
- X}
- X
- X
- X/* --------------------
- X Find all mail items in given folder, throw away folder record if no
- X mail items. Returns next folder in linked list, adds new folder
- X records to linked list if original record overflows.
- X-------------------- */
- Xfolder
- Xfind_mail(flr, load_time)
- X folder flr;
- X int load_time;
- X{
- X struct direct *dp, *readdir();
- X DIR *dirp, *opendir();
- X int i, n = 0, items[MAXITEMS], *itmp = items, dcmp();
- X char str[LEN];
- X item tmp, last = (item) NULL;
- X folder new_folder();
- X
- X (void)sprintf(str, "%s/%s", mail_dir, flr->name);
- X dirp = opendir(str);
- X if(dirp == (DIR *) NULL) {
- X if(load_time)
- X (void)printf("%s: strange folder.\n", str);
- X } else {
- X for(dp=readdir(dirp) ; dp!=(struct direct *) NULL ; dp=readdir(dirp)) {
- X /* get numbers of all mail items */
- X if(n >= MAXITEMS) {
- X no_control();
- X (void)printf("\nMore than %d items in folder.\n",MAXITEMS-1);
- X exit(1);
- X }
- X /* ignore anything that is not string of digits */
- X if(! digits(dp->d_name))
- X continue;
- X /* assume any file that is string of digits is a mail
- X item and not a directory */
- X *itmp = atoi(dp->d_name);
- X n++, itmp++;
- X }
- X (void)closedir(dirp);
- X }
- X if(n == 0) { /* Empty folder - delete from list */
- X flr->valid = EMPTY;
- X if(load_time)
- X (void)printf("\t%s: empty\n", flr->name);
- X if(flr->prev != (folder) NULL)
- X flr->prev->next = flr->next;
- X else
- X folders = flr->next;
- X if(flr->next != (folder) NULL)
- X flr->next->prev = flr->prev;
- X return(flr->next);
- X } else
- X qsort((char *)items, n, sizeof(int), dcmp);
- X if(load_time) /* show status of folder */
- X if(n == 1)
- X (void)printf("\t%s: %d\n", flr->name, *items);
- X else
- X (void)printf("\t%s: %d-%d (%d items)\n",flr->name,*items,*(items+n-1),n);
- X for(i=0, itmp=items ; i < n ; itmp++, i++) {
- X /* add item to list of items in folder */
- X tmp = NEW(mail_item);
- X get_title(flr, tmp, *itmp);
- X if(i % lines == 0 && last != (item) NULL) {
- X /* add new record for folder */
- X flr->last = last;
- X flr = new_folder(flr);
- X last = (item) NULL;
- X }
- X tmp->next = (item) NULL;
- X tmp->prev = last;
- X if(last != (item) NULL)
- X last->next = tmp;
- X else
- X flr->mail = tmp;
- X last = tmp;
- X }
- X flr->last = last;
- X return(flr->next);
- X}
- X
- X
- Xint
- Xdcmp(a, b)
- X int *a, *b;
- X{
- X return(*a - *b);
- X}
- X
- X
- X/* --------------------
- X Return true if string consists only of digits.
- X-------------------- */
- Xint
- Xdigits(str)
- X char *str;
- X{
- X for( ; *str != '\0' ; str++)
- X if(! isdigit(*str))
- X return(false);
- X return(true);
- X}
- X
- X
- X/* --------------------
- X Make header line from mail item.
- X-------------------- */
- Xvoid
- Xget_title(flr, mail, num)
- X folder flr;
- X item mail;
- X int num;
- X{
- X FILE *fp, *fopen();
- X char date[10], str[LEN], subj[42], from[20], to[16], fill[42];
- X char repl = ' ', *first(), *s, *fgets();
- X int i;
- X
- X subj[0] = from[0] = to[0] = fill[0] = '\0';
- X (void)sprintf(str, "%s/%s/%d", mail_dir, flr->name, num);
- X fp = fopen(str, "r");
- X while((s=fgets(str, LEN, fp)) != (char *) NULL && *str != '\n') {
- X /* while not eof and reading header */
- X str[strlen(str)-1] = '\0';
- X /* should also check date */
- X if(! lstrncmp("date:", str, 5))
- X get_date(str+5, date);
- X else if(! lstrncmp("subject:", str, 8)) {
- X s = first(str+8);
- X (void)strncpy(subj, s, 41);
- X subj[41] = '\0';
- X } else if(! lstrncmp("replied:", str, 8))
- X repl = '-';
- X else if(! lstrncmp("from:", str, 5)) {
- X s = first(str+5);
- X if(! isuser(s)) {
- X (void)strncpy(from, s, 19);
- X from[19] = '\0';
- X }
- X } else if(! lstrncmp("to:", str, 3)) {
- X s = first(str+3);
- X (void)strncpy(to, s, 15);
- X to[15] = '\0';
- X } else if(! lstrncmp("apparently-to:", str, 14)) {
- X s = first(str+14);
- X (void)strncpy(to, s, 15);
- X to[15] = '\0';
- X }
- X }
- X if(s != (char *) NULL) {
- X for(i=0 ; i < 42 && fgets(str, LEN, fp) != (char *) NULL ;) {
- X str[strlen(str)-1] = ' ';
- X (void)strncpy(fill+i, str, 42-i);
- X i += strlen(str);
- X }
- X fill[41] = '\0';
- X }
- X (void)fclose(fp);
- X if(subj[0] == '\0')
- X (void)strcpy(subj, "(none)");
- X flatten(subj);
- X flatten(fill);
- X if(from[0] == '\0')
- X (void)sprintf(str, " %8s %cTo: %-15s %s << %s",date,repl,to,subj,fill);
- X else
- X (void)sprintf(str, " %8s %c%-19s %s << %s",date,repl,from,subj,fill);
- X str[cols-6] = '\0';
- X mail->title = NEWSTR(strlen(str)+1);
- X mail->number = num;
- X (void)strcpy(mail->title, str);
- X}
- X
- X
- X#ifdef USDATE
- X#define DAY1 date[3]
- X#define DAY2 date[4]
- X#define MTH1 date[0]
- X#define MTH2 date[1]
- X#else
- X#define DAY1 date[0]
- X#define DAY2 date[1]
- X#define MTH1 date[3]
- X#define MTH2 date[4]
- X#endif
- X#define YR1 date[6]
- X#define YR2 date[7]
- X
- X/* --------------------
- X Get date from first argument; assumes format is one of
- XDate: Fri, 3 Apr 87 ... (a)
- XDate: Wed, 17 Jun 87 ... (b)
- XDate: 07 Sep 87 ... (c)
- XDate: Tue Sep 29 12:27:01 EST 1987 (d)
- X Dates are put into Imperial form (dd-mm-yy), or US form (mm-dd-yy)
- X if -DUSDATE is set.
- X
- X This routine should be more flexible re: recognizing date formats.
- X-------------------- */
- Xvoid
- Xget_date(str, date)
- X char *str, *date;
- X{
- X int i;
- X bool get_month();
- X char *next_token();
- X
- X date[2] = date[5] = '-';
- X date[8] = '\0';
- X for(; *str == ' ' || *str == '\t' ; str++)
- X ;
- X if(*str == '\0')
- X goto unknown;
- X if(! isdigit(*str)) /* day of month not first field */
- X str = next_token(str); /* skip day of week */
- X if(str == (char *) NULL + 1)
- X goto unknown;
- X
- X if(isdigit(*str)) { /* one of (a), (b) or (c) formats */
- X if(isdigit(*(str+1))) /* two-number date */
- X#ifdef USDATE
- X DAY1 = *str, DAY2 = *(++str);
- X else
- X DAY1 = '0', DAY2 = *str;
- X#else
- X DAY1 = (*str == '0') ? ' ' : *str, DAY2 = *(++str);
- X else
- X DAY1 = ' ', DAY2 = *str;
- X#endif
- X str = next_token(str); /* go to month */
- X if(str == (char *) NULL + 1)
- X goto unknown;
- X if(! get_month(str, date))
- X goto unknown;
- X str = next_token(str); /* go to year */
- X if(str == (char *) NULL + 1)
- X goto unknown;
- X if(! isdigit(*str) || ! isdigit(*(str+1)))
- X goto unknown;
- X YR1 = *str, YR2 = *(str+1);
- X } else { /* format (d) */
- X if(! get_month(str, date))
- X goto unknown;
- X str = next_token(str); /* go to day */
- X if(str == (char *) NULL + 1)
- X goto unknown;
- X if(! isdigit(*str) || ! isdigit(*(str+1)))
- X goto unknown;
- X#ifdef USDATE
- X DAY1 = *str, DAY2 = *(++str);
- X#else
- X DAY1 = (*str == '0') ? ' ' : *str, DAY2 = *(++str);
- X#endif
- X str += strlen(str) - 2; /* go to year */
- X if(! isdigit(*str) || ! isdigit(*(str+1)))
- X goto unknown;
- X YR1 = *str, YR2 = *(str+1);
- X }
- X return; /* date is ok */
- X
- Xunknown: /* erase date */
- X for(i=0 ; i < 8 ; i++)
- X date[i] = ' ';
- X}
- X
- X
- Xstatic char *month[] = {
- X "jan", "feb", "mar", "apr", "may", "jun",
- X "jul", "aug", "sep", "oct", "nov", "dec"
- X};
- X
- X/* --------------------
- X Put the month from the first part of str in date as a number.
- X-------------------- */
- Xbool
- Xget_month(str, date)
- X char *str, *date;
- X{
- X int i;
- X
- X for(i=0 ; i < 12 && lstrncmp(month[i], str, 3) != 0 ; i++)
- X ;
- X if(i == 12) /* string doesn't match month */
- X return(false);
- X else {
- X if(i < 9) /* single digit month */
- X#ifdef USDATE
- X MTH1 = ' ', MTH2 = i + '0' + 1;
- X#else
- X MTH1 = '0', MTH2 = i + '0' + 1;
- X#endif
- X else
- X MTH1 = '1', MTH2 = i + '0' - 9;
- X return(true);
- X }
- X}
- X
- X
- X/* --------------------
- X Replace tabs and newlines in string by spaces.
- X Compress multiple spaces to a single space.
- X-------------------- */
- Xvoid
- Xflatten(str)
- X char *str;
- X{
- X char prev = ' ', *s = str;
- X
- X /* advance str monotonically, copying into s as necessary */
- X
- X while (*str)
- X {
- X /* change funny character to space */
- X if (!isgraph(*str)) {
- X *str = ' ';
- X }
- X
- X /* copy character into new position */
- X *s = *str;
- X
- X /* advance new string pointer, but compress multiple spaces */
- X if (isgraph(*str) || prev != ' ') {
- X prev = *s;
- X s++;
- X }
- X str++;
- X }
- X *s = '\0';
- X}
- X
- X
- X/* --------------------
- X Return pointer to first non-white character in string.
- X-------------------- */
- Xchar *
- Xfirst(str)
- X char *str;
- X{
- X for(; *str == ' ' || *str == '\t' || *str == '\n' ; str++)
- X ;
- X return(str);
- X}
- X
- X
- X/* --------------------
- X Check given string for occurence of user's name.
- X-------------------- */
- Xint
- Xisuser(str)
- X char *str;
- X{
- X int len = strlen(user);
- X
- X for(; *str != '\0' ; str++)
- X /* assume all chars in all unames alphanumeric */
- X if(*str == *user && strncmp(str, user, len) == 0 &&
- X (*(str+len) < 'a' || *(str+len) > 'z') &&
- X (*(str+len) < 'A' || *(str+len) > 'Z') &&
- X (*(str+len) < '0' || *(str+len) > '9'))
- X return(true);
- X return(false);
- X}
- X
- X
- X/* --------------------
- X Make a new folder record.
- X-------------------- */
- Xfolder
- Xnew_folder(flr)
- X folder flr;
- X{
- X folder f;
- X
- X f = NEW(mail_folder);
- X f->prev = flr;
- X f->next = flr->next;
- X flr->next = f;
- X if(f->next != (folder) NULL)
- X f->next->prev = f;
- X f->pagenum = f->pages = flr->pages + 1;
- X f->name = flr->name;
- X f->valid = true;
- X f->mail = f->last = (item) NULL;
- X flr = f;
- X for(f=f->prev; f != (folder) NULL && f->name == flr->name ; f=f->prev)
- X f->pages = flr->pages;
- X return(flr);
- X}
- X
- X
- X/* --------------------
- X Find next free slot in directory for mail item (that is, find next
- X unused number) -- structures in vmail may not be up to date if user
- X has initiated a "send" process.
- X-------------------- */
- Xint
- Xnext_vacant(flr)
- X folder flr;
- X{
- X struct direct *dp, *readdir();
- X DIR *dirp, *opendir();
- X char str[LEN];
- X int i, n = 0;
- X
- X (void)sprintf(str, "%s/%s", mail_dir, flr->name);
- X dirp = opendir(str);
- X for(dp=readdir(dirp) ; dp != (struct direct *) NULL ; dp=readdir(dirp)) {
- X /* ignore anything that is not string of digits */
- X if(! digits(dp->d_name))
- X continue;
- X if((i = atoi(dp->d_name)) > n)
- X n = i;
- X }
- X (void)closedir(dirp);
- X return(n+1);
- X}
- END_OF_load.c
- if test 11899 -ne `wc -c <load.c`; then
- echo shar: \"load.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 3 \(of 3\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-